package netbay;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.Channel;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.List;

public class TransactionManager {

	public static String jdbcDriver = "";
	public static String dbUrl = "";
	public static String dbUser = "";
	public static String dbPassword = "";

	public static String JPMCcpaId = "";
	public static String JPMCService = "";
	public static String JPMCAction = "";
	public static String JPMCTransportProtocol = "";
	public static String JPMCTransportEndPoint = "";
	public static String JPMCPayloadType = "";

	public static String recvTcdStatus = "";
	public static String beginSendJpmcStatus = "";
	public static String finSendJpmcStatus = "";
	public static String recvJpmcStatus = "";
	public static String sendTcdStatus = "";
	public static String resendSFTPStatus = "";
	public static String redownloadSFTPStatus = "";

	public TransactionManager() {

		super();

	}

	public TransactionLog findTransactionByAttach(String attachName) {

		String[] cut = attachName.split("-");
		if (cut.length > 1) {
			String converId = cut[1];
			Connection con;
			try {
				con = getConnection();
				PreparedStatement st = TransactionLog.convertFindByConverId(
						converId, con);
				if (st != null) {
					ResultSet rs = st.executeQuery();
					return TransactionLog.convertResultsetToLog(rs);
				}

			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	// public static void main(String arg[])
	// {
	// String configPath = "./WebContent/WEB-INF/config.properties";
	// NetbayUtility.init(configPath);
	//
	// TransactionManager manager = new TransactionManager();
	// TransactionLog log = manager.findTransactionByConverId("AXXX000000006");
	// System.out.println(log);
	// }

	public TransactionLog findTransactionByConverId(String ConverId) {

		Connection con;
		try {
			con = getConnection();
			PreparedStatement st = TransactionLog.convertFindByConverId(
					ConverId, con);
			if (st != null) {
				ResultSet rs = st.executeQuery();
				return TransactionLog.convertResultsetToLog(rs);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}

		return null;
	}

	public Integer saveTransaction(TransactionLog log) {
		Connection con = null;
		Integer id = null;
		ResultSet rs = null;
		try {

			con = getConnection();
			Statement st = con.createStatement();
			String query = TransactionLog.convertInsert(log);
			st.execute(query, Statement.RETURN_GENERATED_KEYS);

			rs = st.getGeneratedKeys();

			if (rs.next()) {
				id = rs.getInt(1);
			}

		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		} finally {
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}

		return id;
	}

	// Obsolete because change the requirement

	// public boolean updateTransaction(TransactionLog log, String propertyName)
	// {
	// Connection con = null;
	// // List resultList = null;
	// try {
	//
	// con = getConnection();
	// PreparedStatement st = log.convertUpdate(propertyName, con);
	// st.executeUpdate();
	//
	// } catch (SQLException e) {
	// e.printStackTrace();
	// return false;
	// } finally {
	// if (con != null) {
	// try {
	// con.close();
	// } catch (SQLException e) {
	// e.printStackTrace();
	// }
	// }
	// }
	//
	// return true;
	// }

	public List getDisplayConversationId(String converId) {

		Connection con = null;
		List resultList = null;
		try {

			con = getConnection();
			PreparedStatement st = TransactionLog.convertFindByConverId(
					converId, con);

			if (st != null) {
				ResultSet rs = st.executeQuery();

				resultList = TransactionLog.convertResultsetToDisplay(rs);
			}

		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		} finally {
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}

		return resultList;
	}

	public List getDisplayTransactionLogRecvTcd(Date fromDate, Date toDate) {
		Connection con = null;
		List resultList = null;
		try {

			con = getConnection();
			PreparedStatement st = TransactionLog.convertQueryRecvTcd(fromDate,
					toDate, con);

			if (st != null) {

				ResultSet rs = st.executeQuery();

				resultList = TransactionLog.convertResultsetToDisplay(rs);
			}

		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		} finally {
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}

		return resultList;
	}

	public List getDisplayTransactionLogRecvJpmc(Date fromDate, Date toDate) {
		Connection con = null;
		List resultList = null;
		try {

			con = getConnection();
			PreparedStatement st = TransactionLog.convertQueryRecvJpmc(
					fromDate, toDate, con);
			if (st != null) {
				ResultSet rs = st.executeQuery();

				resultList = TransactionLog.convertResultsetToDisplay(rs);
			}

		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		} finally {
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}

		return resultList;
	}

	public boolean resendSFTPById(Integer id) {

		TransactionLog log = findTransactionById(id);
		// need to logging for event resend

		return true;
	}

	public boolean redownloadSFTPById(Integer id) {

		TransactionLog log = findTransactionById(id);
		// need to logging for event redownload

		return true;
	}

	public TransactionLog findTransactionById(Integer id) {
		Connection con = null;
		List resultList = null;
		TransactionLog searchLog = null;

		try {
			con = getConnection();
			Statement stmt = con.createStatement();
			PreparedStatement st = TransactionLog.convertFindById(id, con);
			if (st != null) {
				ResultSet rs = st.executeQuery();

				// it's still unclear why it mustn't call next() in this
				// situation
				// in other situation it must call next() to get the first
				// result
				// if(rs.next())
				searchLog = TransactionLog.convertResultsetToLog(rs);
			}

		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		} finally {
			if (con != null) {
				try {
					con.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}

		return searchLog;
	}

	public Connection getConnection() throws SQLException {

		try {
			Class.forName(jdbcDriver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		Connection con = DriverManager.getConnection(dbUrl
				+ "?useUnicode=true&characterEncoding=utf-8", dbUser,
				dbPassword);
		return con;
	}

	public boolean updateJpmcDetail(TransactionLog registeredLog,
			String attachName) {

		// need to check was it process before?
		if (registeredLog.getJpmcAttach() != null
				&& registeredLog.getJpmcAttach().length() > 0)
			return false;

		registeredLog.updateJpmcDetail(attachName);

		try {
			Connection con = getConnection();
			PreparedStatement st = registeredLog.convertUpdateJPMC(con);
			if (st != null) {
				st.executeUpdate();

				return true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}

		return false;

	}

	public boolean insertArchivedToDB(File archive) {
		FileInputStream fis = null;
		boolean Succeed = false;
		try {
			Connection con = getConnection();
			PreparedStatement st = con
					.prepareStatement("insert into archived(id,filename,filecontent) values(NULL,?,?)");

			if (st != null) {
				st.setString(1, archive.getName());
				fis = new FileInputStream(archive);
				st.setBinaryStream(2, (InputStream) fis,
						(int) (archive.length()));

				st.executeUpdate();

				Succeed = true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			Succeed = false;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			Succeed = false;
		} finally {
			if (fis != null)
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}

		return Succeed;
	}

	public boolean insertTraffic(TransactionTraffic traff) {

		try {
			Connection con = getConnection();
			PreparedStatement st = traff.convertInsert(con);
			if (st != null) {
				st.executeUpdate();

				return true;
			}

		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}

		return false;

	}

	// Obsolete because change requirement
	// public boolean getArchivedFromDB(File archive) {
	//
	// boolean Succeed = false;
	// ResultSet rs = null;
	// InputStream is = null;
	// OutputStream out = null;
	// if (!archive.exists()) {
	// try {
	// archive.createNewFile();
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	// }
	// try {
	// Connection con = getConnection();
	// PreparedStatement st = con
	// .prepareStatement("select * from archived where filename = ?");
	// st.setString(1, archive.getName());
	//
	// rs = st.executeQuery();
	//
	// if (rs.next()) {
	// is = rs.getBinaryStream("filecontent");
	// out = new FileOutputStream(archive);
	// byte buf[] = new byte[1024];
	// int len;
	// while ((len = is.read(buf)) > 0) {
	// out.write(buf, 0, len);
	// }
	//
	// Succeed = true;
	// } else {
	// Succeed = false;
	// }
	//
	// } catch (SQLException e) {
	// e.printStackTrace();
	// Succeed = false;
	// } catch (FileNotFoundException e) {
	// e.printStackTrace();
	// Succeed = false;
	// } catch (IOException e) {
	// e.printStackTrace();
	// Succeed = false;
	// } finally {
	// if (is != null) {
	// try {
	//
	// is.close();
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	// }
	// if (out != null) {
	// try {
	// out.close();
	// } catch (IOException e) {
	// e.printStackTrace();
	// }
	// }
	// }
	//
	// return Succeed;
	// }

}
